package thread.wang_bao_ling.c38;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

/**
 *  自己通过消费者和生产者模式实现（缺点：会多出一个创建令牌的线程，且生产令牌的线程在高并发的情况下线程间时间片竞争频繁，并不能保证sleep后能立即执行生产令牌的代码）
 */
public class MySimpleLimiter {
    private static ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
    private static ExecutorService es = Executors.newFixedThreadPool(1);
    public static void main(String[] args) throws InterruptedException {
        product(1);
        final AtomicLong prevTime = new AtomicLong(System.currentTimeMillis());
        for (int i=0; i<20; i++){
            //限流器限流
            acquire();
            //提交任务异步执行
            es.execute(()->{
                //打印时间间隔：毫秒
                long currentTime=System.currentTimeMillis();
                System.out.println(currentTime-prevTime.get());
                prevTime.set(currentTime);
            });
            //每个请求间隔100毫秒
            Thread.sleep(100);
        }

    }

    /**
     * 生成令牌
     * @param speed 每秒钟生成令牌的个数
     */
    public static void product(int speed){
        new Thread(()->{
            while (true) {
                try {
                    queue.offer(new Object());
                    Thread.sleep(1000/speed);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }).start();
    }

    public static void acquire() throws InterruptedException {
        queue.take();
    }
}
